#include "Help.h"
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "Errors.h"
#include "Info.h"
#include "GlobalVariables.h"
#include "Wc.h"

int main(int argc, char** argv) {

	int next_option;
	int state = 0;
	char* inputFilename = NULL;
	int paramCounter = 1; /* Puntero de argumentos que recibe el programa */
	FILE *input = NULL;
	int byteCountMode = 0, lineCountMode = 0, wordCountMode = 0, assemblyMode = 0;
	const char* const short_options = "ahvwlc"; /* Agregar las demas y/o modificar */
	const struct option long_options[] = { { "help", 0, NULL, 'h' }, {
			"version", 0, NULL, 'v' }, { "words", 0, NULL, 'w' }, { "lines", 0,
			NULL, 'l' }, { "bytes", 0, NULL, 'c' }, { "assemblyMode", 0, NULL,
			'a' }, { NULL, 0, NULL, 0 } };

	do {
		next_option = getopt_long(argc, argv, short_options, long_options,
				NULL);
		switch (next_option) {
		case 'h':
			printHelp(argv[0]);
			exit(0);

		case 'v':
			printVersion();
			exit(0);

		case 'w':
			paramCounter++;
			wordCountMode = 1;
			break;

		case 'l':
			paramCounter++;
			lineCountMode = 1;
			break;

		case 'c':
			paramCounter++;
			byteCountMode = 1;
			break;

		case 'a':
			paramCounter++;
			assemblyMode = 1;
			break;

		case '?':
			exit(1);

		default:
			break;
		}

	} while (next_option != -1);

	/* Comportamiento por default igual que en Wc */
	if(!wordCountMode && !lineCountMode && !byteCountMode) {
		wordCountMode = 1;
		lineCountMode = 1;
		byteCountMode = 1;
	}

	/* Contador de archivos */
	int filesCount = argc - paramCounter;

	/* Proceso los archivos, ya sea de stdin o si tengo por parametros */
	if (filesCount == 0) /*Mi archivo viene de stdin*/
	{
		input = stdin;
		if (assemblyMode) {
			input = fileno(input);
		}
		if (wc(input) == ERROR_LECTURA_ARCHIVO) {
			read_file_error("STDIN");
			state = ERROR_LECTURA_ARCHIVO;
		} else {
			info(wordCountMode, lineCountMode, byteCountMode);
			printf("\n");
		}
	} else { /* Mis archivos vienen como parametro */
		if (filesCount > 0) {
			int acumBytes = 0; /* Acumuladores para los archivos */
			int acumLines = 0;
			int acumWords = 0;
			int i;

			for (i = 0; i < filesCount; i++) {
				inputFilename = argv[(paramCounter) + i];
				input = fopen(inputFilename, "rb");
				if (input == NULL) {
					open_file_error(inputFilename);
					state = ERROR_APERTURA_ARCHIVO;
					continue; /* Pasa al siguiente archivo */
				}

				int wcResult;
				/* Proceso cada archivo */
				if (assemblyMode) {
					wcResult = wc(fileno(input));
				} else {
					wcResult = wc(input);
				}

				if (wcResult == ERROR_LECTURA_ARCHIVO) {
					read_file_error(inputFilename);
					state = ERROR_LECTURA_ARCHIVO;
					continue; /* Proceso el siguiente archivo */
				} else {
					infoParam(wordCountMode, lineCountMode, byteCountMode,
							inputFilename);

					acumBytes += characters; /* Acumulo los datos */
					acumLines += lines;
					acumWords += words;
				}

				if (fclose(input) < 0) {
					close_file_error(inputFilename);
					state = ERROR_CIERRE_ARCHIVO;
				}
			}

			// Si tengo mas de un archivo muestro el total
			if (filesCount > 1) {
				infoAcum(wordCountMode, lineCountMode, byteCountMode, acumWords,
						acumLines, acumBytes);
			}

		}

	}

	return state;
}
